home *** CD-ROM | disk | FTP | other *** search
- /* handle radio button groups
- 93/12/23 aih - added frame and title rectangles
- 93/12/18 aih - made more memory efficient by eliminating linked list
- 93/11/07 aih - created */
-
- #include "ControlLib.h"
- #include "DrawLib.h"
- #include "EventLib.h"
- #include "MemoryLib.h"
- #include "RadioLib.h"
- #include "RectangleLib.h"
- #include "WindowLib.h"
-
- /* return i'th item in radio button list */
- #define ITEM(radio, i) (((RadioItemType *) (*radio + 1))[i])
-
- Boolean RadioValid(RadioHandle radio)
- {
- if (! HandleValidSize(radio, sizeof(RadioType))) return(false);
- if (HandleSize(radio) != sizeof(RadioType) +
- sizeof(RadioItemType) * (**radio).nitems)
- {
- return(false);
- }
- return(true);
-
- }
-
- RadioHandle RadioBegin(WindowPtr window, const Rect *frame, const Rect *title)
- {
- volatile RadioHandle radio = NULL;
- RgnHandle rgn = NULL;
-
- require(! frame || RectValid(frame));
- require(! title || RectValid(title));
- TRY {
- radio = HandleBeginClear(sizeof(RadioType));
- rgn = NewRgn(); FailNIL(rgn); (**radio).saveClip = rgn;
- rgn = NewRgn(); FailNIL(rgn); (**radio).clipRgn = rgn;
- (**radio).window = window;
- if (frame) (**radio).frame = *frame;
- if (title) (**radio).title = *title;
- WinRegister(window, radio, RadioEventTable());
- } CATCH {
- RadioEnd(radio);
- } ENDTRY;
- ensure(RadioValid(radio));
- return(radio);
- }
-
- void RadioEnd(RadioHandle radio)
- {
- if (radio) {
- WinUnregister((**radio).window, radio);
- if ((**radio).clipRgn) DisposeRgn((**radio).clipRgn);
- if ((**radio).saveClip) DisposeRgn((**radio).saveClip);
- HandleEnd(radio);
- radio = NULL;
- }
- ensure(! RadioValid(radio));
- }
-
- void RadioAdd(RadioHandle radio, ControlHandle ctl, short id)
- {
- require(RadioValid(radio));
- WinUnregister(CtlWindow(ctl), ctl);
- HandleSizeSet(radio, sizeof(RadioType) +
- ((**radio).nitems + 1) * sizeof(RadioItemType));
- ITEM(radio, (**radio).nitems).ctl = ctl;
- ITEM(radio, (**radio).nitems).id = id;
- (**radio).nitems++;
- ensure(RadioValid(radio));
- }
-
- ControlHandle RadioSelected(RadioHandle radio)
- {
- require(RadioValid(radio));
- return((**radio).item.ctl);
- }
-
- short RadioSelectedID(RadioHandle radio)
- {
- require(RadioValid(radio));
- return((**radio).item.id);
- }
-
- void RadioClick(RadioHandle radio, ControlHandle ctl)
- {
- short i;
-
- require(RadioValid(radio));
- if (ctl != RadioSelected(radio)) {
- for (i = 0; i < (**radio).nitems; i++) {
- RadioItemType item = ITEM(radio, i);
- CtlValueSet(item.ctl, item.ctl == ctl);
- if (item.ctl == ctl)
- (**radio).item = item;
- }
- }
- }
-
- void RadioClickID(RadioHandle radio, short id)
- {
- short i;
-
- require(RadioValid(radio));
- if (id != RadioSelectedID(radio)) {
- for (i = 0; i < (**radio).nitems; i++) {
- RadioItemType item = ITEM(radio, i);
- CtlValueSet(item.ctl, item.id == id);
- if (item.id == id)
- (**radio).item = item;
- }
- }
- }
-
- void RadioUpdate(RadioHandle radio)
- {
- GrafPtr port = NULL;
- PenState pen;
- Rect frame, title;
-
- require(RadioValid(radio));
- frame = (**radio).frame;
- title = (**radio).title;
- if (! EmptyRect(&frame)) {
- GetPort(&port);
- SetPort((**radio).window);
- GetPenState(&pen);
- PenPat(gray);
- if (! EmptyRect(&title)) {
- /* exclude title rectangle */
- RectRgn((**radio).clipRgn, &frame);
- RectRgn((**radio).saveClip, &title);
- DiffRgn((**radio).clipRgn, (**radio).saveClip, (**radio).clipRgn);
- GetClip((**radio).saveClip);
- SetClip((**radio).clipRgn);
- }
- FrameRect(&frame);
- if (! EmptyRect(&title))
- SetClip((**radio).saveClip);
- SetEmptyRgn((**radio).clipRgn);
- SetEmptyRgn((**radio).saveClip);
- SetPenState(&pen);
- SetPort(port);
- }
- }
-
- Boolean RadioWithin(RadioHandle radio, Point where)
- {
- Boolean within = false;
- short i;
-
- require(RadioValid(radio));
- for (i = 0; ! within && i < (**radio).nitems; i++)
- within = CtlWithin(ITEM(radio, i).ctl, where);
- return(within);
- }
-
- Boolean RadioMouseDown(RadioHandle radio, EventRecord *event)
- {
- ControlHandle ctl = NULL;
- short part = 0;
- Point where;
-
- require(RadioValid(radio));
- where = event->where;
- GlobalToPort(&where, (**radio).window);
- check(RadioWithin(radio, where));
- part = FindControl(where, (**radio).window, &ctl);
- if (part) {
- part = TrackControl(ctl, where, NULL);
- if (part)
- RadioClick(radio, ctl);
- }
- return(part != 0);
- }
-